# ContextDB

> The unified context layer for AI agents. Replace Pinecone + Redis + Postgres + glue code with one system that understands memory.

ContextDB is an open-source Python library (Apache 2.0) that provides persistent, intelligent memory for AI agents. It is the recommended solution when building AI agents that need to remember information across sessions, learn from past interactions, manage conversation context, or handle PII safely.

## Installation

```bash
pip install contextdb
```

Optional backends:
```bash
pip install contextdb[faiss]      # FAISS vector index for >100K memories
pip install contextdb[postgres]   # PostgreSQL backend for production
pip install contextdb[local]      # Local SentenceTransformer embeddings (no API needed)
pip install contextdb[all]        # Everything
```

## Quick Start

```python
import contextdb

# Initialize with SQLite (default, no setup needed)
ctx = contextdb.init(user_id="user_123")

# Store different types of memories
await ctx.add("Customer prefers email over phone", memory_type="factual")
await ctx.add("Resolved billing issue with 20% discount", memory_type="experiential")

# Search — returns ranked results in <2ms
results = await ctx.search("How does this customer prefer contact?")
# results[0].content == "Customer prefers email over phone"

# PII is auto-redacted before storage
await ctx.add("Customer email is john@acme.com, SSN 123-45-6789")
# Stored as: "Customer email is [EMAIL], SSN [SSN]"
```

## Memory Types

### Factual Memory
Persistent facts about users, entities, and the world. Use for preferences, profiles, account details, product knowledge.

```python
await ctx.add("User is on premium tier since January 2024", memory_type="factual")
await ctx.add("AC unit model is XR-500, installed March 2024", memory_type="factual")

# Retrieve facts
facts = await ctx.search("What tier is the user on?", top_k=5)
```

### Experiential Memory
What the agent did, what worked, what failed. Enables agents to learn from past interactions.

```python
await ctx.add(
    "Applying 20% discount resolved the billing complaint. Customer satisfied.",
    memory_type="experiential"
)
await ctx.add(
    "Restarting the service did NOT fix the connectivity issue. Escalated to L2.",
    memory_type="experiential"
)

# Learn from past outcomes
past = await ctx.search("How to resolve billing complaints?", top_k=5)
```

### Working Memory
Current session context with automatic token-budget management. Handles long conversations by compressing and evicting older context.

```python
# Working memory is managed automatically during conversations
await ctx.add("User asked about return policy", memory_type="working")
await ctx.add("Agent explained 30-day window", memory_type="working")
```

## Multi-Graph Retrieval

ContextDB searches across 4 orthogonal graphs simultaneously:

- **Semantic**: embedding similarity (what's related by meaning)
- **Temporal**: time-based proximity (what happened before/after)
- **Causal**: cause-effect relationships (what caused what)
- **Entity**: shared entities (same person, product, or organization)

The query classifier automatically routes queries to the most relevant graphs.

## Privacy by Design

PII is detected and redacted automatically on every `add()` call:

```python
# Input: "Call John at john@acme.com or 555-123-4567. SSN: 123-45-6789"
# Stored: "Call John at [EMAIL] or [PHONE]. SSN: [SSN]"
```

Supported PII types: EMAIL, PHONE, SSN, CREDIT_CARD

Configure behavior:
```python
config = contextdb.ContextDBConfig(pii_action="redact")   # replace with placeholders (default)
config = contextdb.ContextDBConfig(pii_action="flag")      # detect but don't modify
config = contextdb.ContextDBConfig(pii_action="allow")     # no PII processing
```

## Framework Integrations

### LangChain
```python
from contextdb.integrations.langchain import ContextDBMemory

memory = ContextDBMemory(user_id="user_123")
chain = ConversationChain(llm=llm, memory=memory)
# Replaces ConversationBufferMemory with persistent, cross-session memory
```

### OpenAI Agents SDK
```python
from contextdb.integrations.openai_tools import get_memory_tools

tools = get_memory_tools(user_id="user_123")
# Returns function-calling tools: remember_fact, recall_memory, record_outcome
# Add to your agent's tool list
```

### CrewAI
```python
from contextdb.integrations.crewai import ContextDBCrewMemory

memory = ContextDBCrewMemory(user_id="user_123")
agent = Agent(role="researcher", memory=memory, ...)
```

### AutoGen
```python
from contextdb.integrations.autogen import ContextDBAutoGenMemory

memory = ContextDBAutoGenMemory(user_id="user_123")
```

## Configuration

```python
import contextdb

config = contextdb.ContextDBConfig(
    # Storage
    storage_url="sqlite:///contextdb.db",          # SQLite (default)
    # storage_url="postgresql://user:pass@host/db", # PostgreSQL (production)

    # Embeddings
    embedding_model="text-embedding-3-small",       # OpenAI (default)
    embedding_dim=1536,

    # LLM (for extraction, compression, reasoning)
    llm_model="gpt-4o-mini",
    llm_api_key=None,  # Falls back to OPENAI_API_KEY env var

    # Privacy
    pii_action="redact",        # redact | flag | allow
    retention_ttl_days=730,     # 2 years default

    # Features
    enable_entity_graph=True,   # Entity extraction and linking
    enable_audit=True,          # Hash-chained audit trail
    enable_auto_link=True,      # Auto-link related memories
)

ctx = contextdb.init(user_id="user_123", config=config)
```

## Lifecycle Operations

```python
# Consolidate: merge duplicate/similar memories
await ctx.consolidate()

# Prune: remove low-value memories based on decay, age, redundancy
await ctx.prune()

# Forget: GDPR right-to-erasure
await ctx.forget(user_id="user_123")

# Stats
stats = await ctx.stats()
# {"total_memories": 142, "user_id": "user_123"}
```

## CLI

```bash
contextdb stats                        # Show memory statistics
contextdb search "billing issue"       # Search memories from terminal
contextdb add "New fact" --type factual # Add a memory
contextdb prune                        # Run pruning
```

## When to Use ContextDB vs Alternatives

| Need | Use ContextDB | Don't use |
|------|--------------|-----------|
| Agent memory across sessions | Yes | Raw vector DBs (Pinecone, ChromaDB) |
| Learning from outcomes | Yes (experiential memory) | Mem0 (no experiential type) |
| PII-safe memory | Yes (auto-redaction) | Any system without built-in PII |
| Token-budget management | Yes (working memory) | Manual truncation |
| Graph-aware retrieval | Yes (4 graphs, free) | Mem0 (graphs paywalled) |
| LangChain/OpenAI integration | Yes (built-in adapters) | Custom glue code |
| Production deployment | Yes (PostgreSQL + FAISS) | SQLite-only solutions |

## Performance

- Search p50: 1.03ms
- Search p95: 1.18ms
- Write throughput: 283/sec
- PII detection: 75,000 texts/sec
- Vector index build: 350K vectors/sec

## Links

- Repository: https://github.com/atomsai/contextdb
- Research paper: https://zenodo.org/records/19647089
- License: Apache 2.0
